/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package traffic;

import com.google.code.eventsonfire.Events;
import comunicacao.GestorZooKeeper;
import comunicacao.RmiClient;
import comunicacao.RmiClientApp;
import entities.Resposta;
import entities.Server;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import main.ConfigGeral;
import resultado.ResultadoHolder;

/**
 *
 * @author Leonardo Lino Nº45340
 * @author Diogo Pires Nº40351
 */
public class TrafegoRunnable implements Runnable {

    public static final int METODO_LIST = 0;
    public static final int METODO_SELECT = 1;
    private int pedidosSeg;
    private int segundos;
    private boolean running = true;
    private GestorZooKeeper zk;

    public TrafegoRunnable(int pedidos, int segundos, GestorZooKeeper zk) {
        this.pedidosSeg = pedidos;
        this.segundos = segundos;
        this.zk = zk;
    }

    @Override
    public void run() {
        //Events.fire(this, "ola");
        perform2();
    }

     private void perform2() {


        for (int i = 1; i <= segundos; i++) {
            long acumulado = 0;
            long start = System.currentTimeMillis();
            
            for (int j = 0; j < pedidosSeg; j++) {
                //acção para realizar
                invokeRemote(i);

                long finish = System.currentTimeMillis();
                acumulado += finish - start;
                start = finish;
                
                if(acumulado > 1000)
                    break;
            }


            if (acumulado < 1000) {
                try {
                    Thread.sleep(1000 - acumulado);
                } catch (InterruptedException ex) {
                    Logger.getLogger(TrafegoRunnable.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    private void invokeRemote(int segundo) {

        ResultadoHolder res = ResultadoHolder.getInstance();

        if (ControladorTrafego.selectedServer.getType() == Server.TYPE_DB) {

            if (selectMetodoRmiClient()) {
                res.incrementOK(segundo, 1);
            } else {
                res.incrementFail(segundo, 1);
            }
        } else {

            if (selectMethodAppServer()) {
                res.incrementOK(segundo, 1);
            } else {
                res.incrementFail(segundo, 1);
            }
            
        }

    }

    private boolean selectMethodAppServer() {
        RmiClientApp rmiClient = new RmiClientApp();
        rmiClient.selectedServer(ControladorTrafego.selectedServer);
        Resposta resposta = null;

        if (GestorThreads.metodo_list && GestorThreads.metodo_select) {
            Random rn = new Random();
            int metodo = rn.nextInt(2);

            if (metodo == METODO_LIST) {
                resposta = rmiClient.listaTeatros();
            } else {
                resposta = rmiClient.getTeatro(randomTeatroName());
            }

        } else if (GestorThreads.metodo_list) {
            resposta = rmiClient.listaTeatros();
        } else if (GestorThreads.metodo_select) {
            resposta = rmiClient.getTeatro(randomTeatroName());
        }

        if (resposta == null) {
            return false;
        } else {
            return true;
        }
    }

    private boolean selectMetodoRmiClient() {

        RmiClient rmiClient = new RmiClient(zk);

        if (GestorThreads.metodo_list && GestorThreads.metodo_select) {
            Random rn = new Random();
            int metodo = rn.nextInt(2);

            if (metodo == METODO_LIST) {
                return rmiClient.connectList();
            } else {
                return rmiClient.connectSelect(randomTeatroName());
            }

        } else if (GestorThreads.metodo_list) {
            return rmiClient.connectList();
        } else if (GestorThreads.metodo_select) {
            return rmiClient.connectSelect(randomTeatroName());
        }

        return false;
    }
    
    
    private String randomTeatroName(){
        Random rn = new Random();
        int num = rn.nextInt(ConfigGeral.NUMEATROS);
        if (num==0)
            num = 1;
        String str = "teatro"+ num;
        
        return str;
    }

}
